#!/bin/bash
#
#  (clandestine.googlecode.com)  libclandestine: yet another script kiddie's bash framework
#
Use vars
#
# Declarations
#
IP_MASKS=(
	0
	$((0x80000000)) $((0xC0000000)) $((0xE0000000)) $((0xF0000000))
	$((0xF8000000)) $((0xFC000000)) $((0xFE000000)) $((0xFF000000))
	$((0xFF800000)) $((0xFFC00000)) $((0xFFE00000)) $((0xFFF00000))
	$((0xFFF80000)) $((0xFFFC0000)) $((0xFFFE0000)) $((0xFFFF0000))
	$((0xFFFF8000)) $((0xFFFFC000)) $((0xFFFFE000)) $((0xFFFFF000))
	$((0xFFFFF800)) $((0xFFFFFC00)) $((0xFFFFFE00)) $((0xFFFFFF00))
	$((0xFFFFFF80)) $((0xFFFFFFC0)) $((0xFFFFFFE0)) $((0xFFFFFFF0))
	$((0xFFFFFFF8)) $((0xFFFFFFFC)) $((0xFFFFFFFE)) $((0xFFFFFFFF))
	-1
)
readonly IP_MASKS

######################################################################
#
# x.x.x.x -> decimal and vice versa
#
function ip_Quad2Dec () { (( $# > 0 )) || return 0
	declare -- QUAD  Q1  Q2  Q3  Q4
	for QUAD; do
		(( Q1 = Q2 = Q3 = Q4 = 0 )) || true
		IFS="." read Q1 Q2 Q3 Q4 <<< "$QUAD"
		Integers Q1 Q2 Q3 Q4
		if (( Q1 >= 0 && Q1 < 256 && Q2 >= 0 && Q2 < 256 && Q3 >= 0 && Q3 < 256 && Q4 >= 0 && Q4 < 256 )); then
			echo "$(( (Q1 << 24) + (Q2 << 16) + (Q3 << 8) + Q4 ))"
		else
			echo '0'
			Debug "IP dotted quad [$QUAD] seems invalid"
		fi
	done
}
function ip_Dec2Quad () { (( $# > 0 )) || return 0
	declare -i Q1  Q2  Q3  Q4
	declare -- DEC
	for DEC; do
		Integers DEC
		if (( DEC >= 0 && DEC <= 0xFFFFFFFF )); then
			let 'Q1 = (DEC >> 24 << 24)'                || true
			let 'Q2 = (DEC >> 16 << 16) - Q1'           || true
			let 'Q3 = (DEC >> 8  << 8 ) - Q1 - Q2'      || true
			let 'Q4 = (DEC            ) - Q1 - Q2 - Q3' || true
			let 'Q1 = Q1 >> 24' || true
			let 'Q2 = Q2 >> 16' || true
			let 'Q3 = Q3 >> 8'  || true
			echo "$Q1.$Q2.$Q3.$Q4"
		else
			echo ''
			Debug "decimal IP address [$DEC] seems invalid"
		fi
	done
}

######################################################################
#
# Echoes class, default prefix and description of an address given in numeric form.
#
function ip_GetClass () { (( $# > 0 )) || { echo '- 32 No address given'; return 255; }
	declare -- ADDRESS="$1"
	Integers ADDRESS
	# class A
	(( ADDRESS >= 0          && ADDRESS <= 0x00FFFFFF )) && { echo 'A 8 "This" Network'; return 0; } # 0.0.0.0/8
	(( ADDRESS >= 0x0A000000 && ADDRESS <= 0x0AFFFFFF )) && { echo 'A 8 Private-Use Networks'; return 0; } # 10.0.0.0/8
	(( ADDRESS >= 0x0E000000 && ADDRESS <= 0x0EFFFFFF )) && { echo 'A 8 Public-Data Networks'; return 0; } # 14.0.0.0/8
	(( ADDRESS >= 0x7F000000 && ADDRESS <= 0x7FFFFFFF )) && { echo 'A 8 Loopback'; return 0; } # 127.0.0.0/8
	(( ADDRESS >= 0          && ADDRESS <= 0x7FFFFFFF )) && { echo 'A 8'; return 0; } # 0.0.0.0 - 127.255.255.255
	# class B
	(( ADDRESS >= 0xA9FE0000 && ADDRESS <= 0xA9FEFFFF )) && { echo 'B 16 Link Local'; return 0; } # 169.254.0.0/16
	(( ADDRESS >= 0xAC100000 && ADDRESS <= 0xAC1FFFFF )) && { echo 'B 16 Private-Use Networks'; return 0; } # 172.16.0.0/12
	(( ADDRESS >= 0x80000000 && ADDRESS <= 0xBFFFFFFF )) && { echo 'B 16'; return 0; } # 128.0.0.0 - 191.255.255.255
	# class C
	(( ADDRESS >= 0xC0000200 && ADDRESS <= 0xC00002FF )) && { echo 'C 24 Test-Net'; return 0; } # 192.0.2.0/24
	(( ADDRESS >= 0xC0A80000 && ADDRESS <= 0xC0A8FFFF )) && { echo 'C 24 Private-Use Networks'; return 0; } # 192.168.0.0/16
	(( ADDRESS >= 0xC0586300 && ADDRESS <= 0xC05863FF )) && { echo 'C 24 6to4 Relay Anycast'; return 0; } # 192.88.99.0/24
	(( ADDRESS >= 0xC6120000 && ADDRESS <= 0xC613FFFF )) && { echo '- 15 Network Interconnect Device Benchmark Testing'; return 0; } # 198.18.0.0/15
	(( ADDRESS >= 0xC0000000 && ADDRESS <= 0xDFFFFFFF )) && { echo 'C 24'; return 0; } # 192.0.0.0 - 223.255.255.255
	# classes D and E
	(( ADDRESS >= 0xE0000000 && ADDRESS <= 0xEFFFFFFF )) && { echo 'D 4 Multicast'; return 0; } # 224.0.0.0/4
	(( ADDRESS >= 0xF0000000 && ADDRESS <= 0xFFFFFFFE )) && { echo 'E 4 Reserved for Future Use'; return 0; } # 240.0.0.0 - 255.255.255.254
	(( ADDRESS = 0xFFFFFFFF ))                           && { echo '- 32 Limited Broadcast'; return 0; } # 255.255.255.255
	# that should cover all possible addresses, so here is an invalid address
	Debug "numeric IP address [$ADDRESS] seems to be invalid"
	echo '- 32 Invalid address'
	return 255
}

######################################################################
#
# Returns all sensible info about the network given
#
function IPCalc () { (( $# > 0 )) || return 255
	declare -- INPUT
	for INPUT; do
		declare -a ADDRESSES  NETMASKS
		IFS=$'\t\n -+~,:;|*^%#@' read -a ADDRESSES <<< "$INPUT"

		declare -p ADDRESSES

exit 0

#		IFS='/' read ADDRESS NETMASK <<< "$ADDRESS"
#		[[ "$NETMASK" ]] || read ADDRESS NETMASK <<< "$ADDRESS"





#		[[ "$ADDRESS" =~ '.' ]] && ADDRESS=`ip_Quad2Dec "$ADDRESS"`


#		ip_GetClass "$ADDRESS" || return 255





#		[[ "$NETMASK" ]] || if (( $# > 1 )); then NETMASK="$2"; else NETMASK="$CLASS_MASK"; fi


#		Integers ADDRESS
#		ADDRESS=`ip_Dec2Quad "$ADDRESS"`

# given address
# network address
# netmask
# netmask prefix
# wildcard
# broadcast
# first host
# last host
# hosts count
# class (A, B, C, D, E)
# class description




#		echo "$ADDRESS"
		unset ADDRESSES NETMASKS
	done
}
